#ifndef TWIN_H
#define TWIN_H

#include "tapi32v.h"
#include "tmisc.h"

#define BUTTON_CLASS		"BUTTON"
#define COMBOBOX_CLASS		"COMBOBOX"
#define EDIT_CLASS			"EDIT"
#define LISTBOX_CLASS		"LISTBOX"
#define MDICLIENT_CLASS		"MDICLIENT"
#define SCROLLBAR_CLASS		"SCROLLBAR"
#define STATIC_CLASS		"STATIC"


class TWin : public THashObj
{
public:
	TWin( TWin* parent = NULL );
	virtual ~TWin();

	HWND	_hWnd;

	virtual void Show( int mode = SW_SHOWDEFAULT );
	virtual bool Create( LPCSTR className = NULL, LPCSTR title = "", 
		DWORD style = ( WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN ),
		DWORD exStyle = 0, HMENU hMenu = NULL );
	virtual bool CreateU8( LPCSTR className = NULL, LPCSTR title = "", 
		DWORD style = ( WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN ),
		DWORD exStyle = 0, HMENU hMenu = NULL );
	virtual bool CreateV( const void* className = NULL, const void* title = "", 
		DWORD style = ( WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN ),
		DWORD exStyle = 0, HMENU hMenu = NULL );
	virtual void Destroy();

	virtual BOOL EvCommand( WORD notifyCode, WORD id, LPARAM hWndCtrl );
	virtual BOOL EvSysCommand( WPARAM cmdType, POINTS pos );
	virtual BOOL EvCreate( LPARAM lParam );
	virtual BOOL EvClose( void );
	virtual BOOL EvNcDestroy( void );
	virtual BOOL EvQueryEndSession( BOOL session, BOOL logOut );
	virtual BOOL EvEndSession( BOOL session, BOOL logOut );
	virtual BOOL EvQueryOpen( void );
	virtual BOOL EvPaint( void );
	virtual BOOL EvNcPaint( HRGN hRgn );
	virtual BOOL EvSize( UINT sizeType, WORD width, WORD height );
	virtual BOOL EvShowWindow( BOOL show, int status );
	virtual BOOL EvGetMinMaxInfo( MINMAXINFO* info );
	virtual BOOL EvTimer( WPARAM timerId, TIMERPROC proc );
	virtual BOOL EvSetCursor( HWND cursorWnd, WORD hitTest, WORD mouseMsg );
	virtual BOOL EvMouseMove( UINT keys, POINTS pos );
	virtual BOOL EvNcHitTest( POINTS pos, LRESULT* result );
	virtual BOOL EvMeasureItem( UINT ctrlId, MEASUREITEMSTRUCT* mis );
	virtual BOOL EvDrawItem( UINT ctrlId, DRAWITEMSTRUCT* dis );
	virtual BOOL EvMenuSelect( UINT item, UINT flag, HMENU hMenu );
	virtual BOOL EvDropFiles( HDROP hDrop );
	virtual BOOL EvNotify( UINT ctrlId, NMHDR* hdr );
	virtual BOOL EvContextMenu( HWND childWnd, POINTS pos );
	virtual BOOL EvHotKey( int hotKey );

	virtual BOOL	EventActivateApp( BOOL fActivate, DWORD dwThreadID );
	virtual BOOL	EventActivate( BOOL fActivate, DWORD fMinimized, HWND hActiveWnd );
	virtual BOOL	EventScroll( UINT uMsg, int nCode, int nPos, HWND scrollBar );

	virtual BOOL	EventButton( UINT uMsg, int nHitTest, POINTS pos );
	virtual BOOL	EventKey( UINT uMsg, int nVirtKey, LONG lKeyData );
	virtual BOOL	EventInitMenu( UINT uMsg, HMENU hMenu, UINT uPos, BOOL fSystemMenu );
	virtual BOOL	EventCtlColor( UINT uMsg, HDC hDcCtl, HWND hWndCtl, HBRUSH *result );
	virtual BOOL	EventFocus( UINT uMsg, HWND focusWnd );
	virtual BOOL	EventSystem( UINT uMsg, WPARAM wParam, LPARAM lParam );
	virtual BOOL	EventUser( UINT uMsg, WPARAM wParam, LPARAM lParam );

	virtual UINT	GetDlgItemText( int ctlId, LPSTR buf, int len );
	virtual UINT	GetDlgItemTextV( int ctlId, void *buf, int len );
	virtual UINT	GetDlgItemTextU8( int ctlId, char *buf, int len );
	virtual BOOL	SetDlgItemText( int ctlId, LPCSTR buf );
	virtual BOOL	SetDlgItemTextV( int ctlId, const void *buf );
	virtual BOOL	SetDlgItemTextU8( int ctlId, const char *buf );
	virtual int		GetDlgItemInt( int ctlId, BOOL *err = NULL, BOOL sign = TRUE );
	virtual BOOL	SetDlgItemInt( int ctlId, int val, BOOL sign = TRUE );
	virtual HWND	GetDlgItem( int ctlId );
	virtual BOOL	CheckDlgButton( int ctlId, UINT check );
	virtual UINT	IsDlgButtonChecked( int ctlId );
	virtual BOOL	IsWindowVisible(void);
	virtual BOOL	EnableWindow(BOOL is_enable);

	virtual	int		MessageBox( LPCSTR msg, LPCSTR title = "msg", UINT style = MB_OK );
	virtual	int		MessageBoxV( void* msg, void* title = TAPI32V::EMPTY_STR_V, UINT style = MB_OK );
	virtual	int		MessageBoxU8( char* msg, char* title="msg", UINT style = MB_OK );
	virtual BOOL	BringWindowToTop(void);
	virtual BOOL	SetForegroundWindow(void);
	virtual BOOL	SetForceForegroundWindow(void);
	virtual BOOL	ShowWindow(int mode);
	virtual BOOL	PostMessage( UINT uMsg, WPARAM wParam, LPARAM lParam );
	virtual BOOL	PostMessageW( UINT uMsg, WPARAM wParam, LPARAM lParam );
	virtual BOOL	PostMessageV( UINT uMsg, WPARAM wParam, LPARAM lParam );
	virtual LRESULT	SendMessage( UINT uMsg, WPARAM wParam, LPARAM lParam );
	virtual LRESULT	SendMessageW( UINT uMsg, WPARAM wParam, LPARAM lParam );
	virtual LRESULT	SendMessageV(UINT uMsg, WPARAM wParam, LPARAM lParam);
	virtual LRESULT	SendDlgItemMessage(int ctlId, UINT uMsg, WPARAM wParam, LPARAM lParam);
	virtual LRESULT	SendDlgItemMessageW(int ctlId, UINT uMsg, WPARAM wParam, LPARAM lParam);
	virtual LRESULT	SendDlgItemMessageV(int ctlId, UINT uMsg, WPARAM wParam, LPARAM lParam);
	virtual BOOL	GetWindowRect( RECT* rect=NULL );
	virtual BOOL	SetWindowPos( HWND hInsAfter, int x, int y, int cx, int cy, UINT fuFlags );
	virtual HWND	SetActiveWindow(void);
	virtual int		GetWindowText( LPSTR text, int size );
	virtual BOOL	SetWindowText( LPCSTR text );
	virtual BOOL	GetWindowTextV( void* text, int size );
	virtual BOOL	GetWindowTextU8( char* text, int size );
	virtual BOOL	SetWindowTextV( const void* text );
	virtual BOOL	SetWindowTextU8( const char* text );
	virtual int		GetWindowTextLengthV(void);
	virtual int		GetWindowTextLengthU8(void);

	virtual LONG_PTR SetWindowLong( int index, LONG_PTR val );
	virtual WORD	SetWindowWord( int index, WORD val );
	virtual LONG_PTR GetWindowLong( int index );
	virtual WORD	GetWindowWord( int index );
	virtual TWin	*GetParent(void) { return _parent; };
	virtual void	SetParent(TWin* parent) { _parent = parent; };
	virtual BOOL	MoveWindow(int x, int y, int cx, int cy, int bRepaint);
	virtual BOOL	Sleep(UINT mSec);
	virtual BOOL	Idle(void);
	virtual RECT	*Rect() { return &_rect; }

	virtual	BOOL	PreProcMsg( MSG* msg );
	virtual	LRESULT	WinProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
	virtual	LRESULT	DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam);

protected:
	RECT			_rect;
	RECT			_orgRect;
	HACCEL			_hAccel;
	TWin*			_parent;
	BOOL			_sleepBusy;	// for TWin::Sleep() only
};

class TSubClass : public TWin 
{
public:
	TSubClass( TWin* parent = NULL );
	virtual ~TSubClass();

	virtual BOOL	AttachWnd( HWND hWnd );
	virtual BOOL	DetachWnd();
	virtual	LRESULT	DefWindowProc( UINT uMsg, WPARAM wParam, LPARAM lParam );

protected:
	WNDPROC		_oldProc;
};

/*
 *	
 */
class TSubClassCtl : public TSubClass 
{
public:
	TSubClassCtl(TWin *_parent);

	virtual	BOOL	PreProcMsg(MSG *msg);
};

/*
 *	
 */
class TWinHashTbl : public THashTbl
{
public:
	TWinHashTbl( int hashNumb ) : THashTbl( hashNumb ){}
	~TWinHashTbl(){}

	unsigned MakeHashId( HWND hWnd ){ return (unsigned)hWnd * 0xf3f77d13; }

protected:
	virtual bool IsSameVal( THashObj* obj, const void* val )
	{
		return static_cast<TWin*>( obj )->_hWnd == *(HWND*)val;
	}
};

#endif // TWIN_H